package cn.song.freight.domain.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * 策略区域定价数据传输对象 (DTO)
 * <pre>
 * V3版本调整：删除areaId字段，新增name和description字段。
 * 用于定价配置信息的数据传输和验证。
 * 支持新增、编辑定价配置的前后端数据交互。
 *
 * 主要用途：
 * - 前端表单数据提交
 * - API接口参数传递
 * - 数据验证和转换
 * - 批量操作的数据载体
 *
 * 验证规则：
 * - 策略ID必须提供且大于0
 * - 定价配置名称不能为空
 * - 首重和续重重量不能为负数
 * - 首重和续重费用和抛重比不能为负数
 *
 * @author SongRenShuo
 * @version 3.0.0
 * @since 2025-08-25
 * </pre>
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "策略区域定价数据传输对象")
public class StrategyAreaPricingDTO {

    /**
     * 主键ID（编辑时使用）
     */
    @ApiModelProperty(value = "主键ID（编辑时必填）")
    private Long id;

    /**
     * 运费策略ID
     */
    @NotNull(message = "运费策略ID不能为空")
    @ApiModelProperty(value = "运费策略ID", required = true, example = "1")
    private Long strategyId;

    /**
     * 定价配置名称
     */
    @NotNull(message = "定价配置名称不能为空")
    @ApiModelProperty(value = "定价配置名称", required = true, example = "华东标准定价")
    private String name;

    /**
     * 定价配置描述
     */
    @ApiModelProperty(value = "定价配置描述", example = "适用于华东地区的标准定价配置")
    private String description;

    /**
     * 首重重量（kg）
     */
    @NotNull(message = "首重重量不能为空")
    @DecimalMin(value = "0", message = "首重重量不能为负数")
    @ApiModelProperty(value = "首重重量（kg）", required = true, example = "1.0000")
    private BigDecimal firstWeightKg;

    /**
     * 首重资费（元）
     */
    @NotNull(message = "首重资费不能为空")
    @DecimalMin(value = "0", message = "首重资费不能为负数")
    @ApiModelProperty(value = "首重资费（元）", required = true, example = "10.0000")
    private BigDecimal firstWeightFee;

    /**
     * 续重重量（kg）
     */
    @NotNull(message = "续重重量不能为空")
    @DecimalMin(value = "0", message = "续重重量不能为负数")
    @ApiModelProperty(value = "续重重量（kg）", required = true, example = "0.5000")
    private BigDecimal additionalWeightKg;

    /**
     * 续重资费（元）
     */
    @NotNull(message = "续重资费不能为空")
    @DecimalMin(value = "0", message = "续重资费不能为负数")
    @ApiModelProperty(value = "续重资费（元）", required = true, example = "3.0000")
    private BigDecimal additionalWeightFee;

     /**
     * 抛重比（如6000表示1m³按6000kg计费），0表示不启用体积重
     */
    @NotNull(message = "抛重比不能为空")
    @DecimalMin(value = "0", message = "抛重比不能为负数")
    @ApiModelProperty(value = "抛重比（如6000表示1m³按6000kg计费），0表示不启用体积重", required = true, example = "6000")
    private BigDecimal volumetricWeightRatio;


    /**
     * 操作人
     */
    @ApiModelProperty(value = "操作人", example = "admin")
    private String operator;

    // ================================
    // 业务方法
    // ================================

    /**
     * 检查DTO数据的基本有效性
     * @return true-有效，false-无效
     */
    public boolean isValid() {
        return strategyId != null && strategyId > 0
                && name != null && !name.trim().isEmpty()
                && firstWeightKg != null && firstWeightKg.compareTo(BigDecimal.ZERO) >= 0
                && firstWeightFee != null && firstWeightFee.compareTo(BigDecimal.ZERO) >= 0
                && additionalWeightKg != null && additionalWeightKg.compareTo(BigDecimal.ZERO) >= 0
                && additionalWeightFee != null && additionalWeightFee.compareTo(BigDecimal.ZERO) >= 0
                && volumetricWeightRatio != null && volumetricWeightRatio.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 是否为新增操作
     * @return true-新增，false-编辑
     */
    public boolean isCreate() {
        return id == null;
    }

    /**
     * 获取定价配置的简要描述
     * @return 描述字符串
     */
    public String getDescription() {
        if (!isValid()) {
            return "无效配置";
        }
        return String.format("首重%skg/%s元，续重%skg/%s元，抛重比%s",
                firstWeightKg, firstWeightFee,
                additionalWeightKg, additionalWeightFee,volumetricWeightRatio);
    }
}
